#include "LPC11xx.h"
#include "bitops.h"
#include "digit.h"

#define DOT 0x40

/*
 *     1
 *    ---
 * 4 | 3 | 2
 *    ---
 * 5 |   | 7
 *    ---  . 6
 *     0
 */
const unsigned char segcode[16] = {
  // 0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    A,    b,    C,    d,    E,    F,
  0xb7, 0x84, 0x2f, 0x8f, 0x9c, 0x9b, 0xbb, 0x86, 0xbf, 0x9f, 0xbe, 0xb9, 0x33, 0xad, 0x3b, 0x3a,
};

//初始化7段数码管
void digit_init(void)
{
  //PIO2_11 -> DS
  //PIO2_10 -> CLK
  //PIO2_9  -> CS
  
  //启用IOCONFIG模块
  setbit(LPC_SYSCON->SYSAHBCLKCTRL, 16);
  
  //将所有引脚配置为GPIO功能
  setbits(LPC_IOCON->PIO2_11, 0, 2, 0);
  setbits(LPC_IOCON->PIO2_10, 0, 2, 0);
  setbits(LPC_IOCON->PIO2_9, 0, 2, 0);
  
  //启用GPIO模块
  setbit(LPC_SYSCON->SYSAHBCLKCTRL, 6);
  
  //将锁存引脚设置为高电平输出
  setbit(LPC_GPIO2->DATA, 9);
  setbit(LPC_GPIO2->DIR, 9);
  
  //将时钟引脚设置为低电平输出
  clrbit(LPC_GPIO2->DATA, 10);
  setbit(LPC_GPIO2->DIR, 10);
  
  //将数据引脚设置为低电平输出
  clrbit(LPC_GPIO2->DATA, 11);
  setbit(LPC_GPIO2->DIR, 11);
  
  //关闭所有LED
  digit_show(0);
}

void digit_show(unsigned char code)
{
  uint8_t i;

  //将锁存引脚拉低
  clrbit(LPC_GPIO2->DATA, 9);

  for (i = 0; i < 8; i++)
  {
    //每个bit位，时钟引脚产生上升沿
    clrbit(LPC_GPIO2->DATA, 10);

    if (chkbit(code, 0)) //判断最低有效位，LSB先发送
    {
      clrbit(LPC_GPIO2->DATA, 11); //共阳极，低电平点亮
    }
    else
    {
      setbit(LPC_GPIO2->DATA, 11);
    }

    setbit(LPC_GPIO2->DATA, 10);
    code = code >> 1; //右移
  }
  
  //将锁存的内容显示到数码管上
  setbit(LPC_GPIO2->DATA, 9);
}
